package com.zenithmind.task.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zenithmind.common.context.UserContext;
import com.zenithmind.common.exception.BusinessException;
import com.zenithmind.common.result.PageResult;
import com.zenithmind.common.utils.BeanCopyUtils;
import com.zenithmind.task.enums.TaskType;
import com.zenithmind.task.mapper.TaskMapper;
import com.zenithmind.task.pojo.entity.Task;
import com.zenithmind.task.pojo.query.TaskQuery;
import com.zenithmind.task.pojo.vo.TaskVO;
import com.zenithmind.task.service.TaskService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 任务服务实现类
 * 
 * @author ZenithMind Team
 * @since 2025-01-09
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task> implements TaskService {

    @Override
    public PageResult<TaskVO> getTaskPage(TaskQuery query, String userId) {
        Page<Task> page = query.toPage();

        LambdaQueryWrapper<Task> wrapper = new LambdaQueryWrapper<>();

        // 基础查询条件
        wrapper.like(StringUtils.hasText(query.getTitle()), Task::getTitle, query.getTitle())
               .like(StringUtils.hasText(query.getDescription()), Task::getDescription, query.getDescription())
               .in(query.getStatusList() != null && !query.getStatusList().isEmpty(), Task::getStatus, query.getStatusList())
               .in(query.getPriorityList() != null && !query.getPriorityList().isEmpty(), Task::getPriority, query.getPriorityList())
               .in(query.getTaskTypeList() != null && !query.getTaskTypeList().isEmpty(), Task::getTaskType, query.getTaskTypeList())
               .in(query.getCategoryIds() != null && !query.getCategoryIds().isEmpty(), Task::getCategoryId, query.getCategoryIds())
               .in(query.getCreatorIds() != null && !query.getCreatorIds().isEmpty(), Task::getCreatorId, query.getCreatorIds())
               .in(query.getAssigneeIds() != null && !query.getAssigneeIds().isEmpty(), Task::getAssigneeId, query.getAssigneeIds())
               .in(query.getProjectIds() != null && !query.getProjectIds().isEmpty(), Task::getProjectId, query.getProjectIds())
               .eq(StringUtils.hasText(query.getParentId()), Task::getParentId, query.getParentId());

        // 时间范围查询
        if (query.getPlannedStartTimeBegin() != null) {
            wrapper.ge(Task::getPlannedStartTime, query.getPlannedStartTimeBegin());
        }
        if (query.getPlannedStartTimeEnd() != null) {
            wrapper.le(Task::getPlannedStartTime, query.getPlannedStartTimeEnd());
        }
        if (query.getPlannedEndTimeBegin() != null) {
            wrapper.ge(Task::getPlannedEndTime, query.getPlannedEndTimeBegin());
        }
        if (query.getPlannedEndTimeEnd() != null) {
            wrapper.le(Task::getPlannedEndTime, query.getPlannedEndTimeEnd());
        }
        if (query.getCreateTimeBegin() != null) {
            wrapper.ge(Task::getCreateTime, query.getCreateTimeBegin());
        }
        if (query.getCreateTimeEnd() != null) {
            wrapper.le(Task::getCreateTime, query.getCreateTimeEnd());
        }

        // 进度范围查询
        if (query.getProgressMin() != null) {
            wrapper.ge(Task::getProgress, query.getProgressMin());
        }
        if (query.getProgressMax() != null) {
            wrapper.le(Task::getProgress, query.getProgressMax());
        }

        // 布尔条件查询
        if (query.getIsImportant() != null) {
            wrapper.eq(Task::getIsImportant, query.getIsImportant() ? 1 : 0);
        }
        if (query.getIsUrgent() != null) {
            wrapper.eq(Task::getIsUrgent, query.getIsUrgent() ? 1 : 0);
        }

        // 关键词搜索
        if (StringUtils.hasText(query.getKeyword())) {
            wrapper.and(w -> w.like(Task::getTitle, query.getKeyword())
                             .or()
                             .like(Task::getDescription, query.getKeyword()));
        }

        // 排序
        wrapper.orderByDesc(Task::getCreateTime);

        IPage<Task> result = page(page, wrapper);

        List<TaskVO> voList = result.getRecords().stream()
            .map(task -> convertToVO(task, userId))
            .collect(Collectors.toList());

        return PageResult.of(voList, result.getTotal());
    }

    @Override
    public TaskVO getTaskById(String id, String userId) {
        Task task = getById(id);
        if (task == null) {
            throw new BusinessException("任务不存在");
        }
        
        return convertToVO(task, userId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean createTask(Task task, String userId) {
        // 设置创建者信息
        task.setCreatorId(userId);
        
        // 设置默认值
        if (task.getStatus() == null) {
            task.setStatus(1); // 待办
        }
        if (task.getPriority() == null) {
            task.setPriority(2); // 中等优先级
        }
        if (task.getProgress() == null) {
            task.setProgress(0);
        }
        if (task.getCompletionRate() == null) {
            task.setCompletionRate(0);
        }
        
        // 设置任务路径（用于子任务）
        if (StringUtils.hasText(task.getParentId())) {
            Task parentTask = getById(task.getParentId());
            if (parentTask != null) {
                task.setLevel(parentTask.getLevel() + 1);
                task.setPath(parentTask.getPath() + "/" + task.getId());
            }
        } else {
            task.setLevel(1);
            task.setPath("/" + task.getId());
        }
        
        boolean result = save(task);
        
        if (result) {
            log.info("用户 {} 创建任务: {}", userId, task.getTitle());
            // TODO: 发送通知、记录日志等
        }
        
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateTask(Task task, String userId) {
        Task existingTask = getById(task.getId());
        if (existingTask == null) {
            throw new BusinessException("任务不存在");
        }
        
        // 权限检查
        if (!checkTaskPermission(existingTask, userId, "edit")) {
            throw new BusinessException("无权限编辑该任务");
        }
        
        boolean result = updateById(task);
        
        if (result) {
            log.info("用户 {} 更新任务: {}", userId, task.getTitle());
            // TODO: 记录变更日志、发送通知等
        }
        
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteTask(String id, String userId) {
        Task task = getById(id);
        if (task == null) {
            throw new BusinessException("任务不存在");
        }
        
        // 权限检查
        if (!checkTaskPermission(task, userId, "delete")) {
            throw new BusinessException("无权限删除该任务");
        }
        
        // 检查是否有子任务
        LambdaQueryWrapper<Task> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Task::getParentId, id);
        long subtaskCount = count(wrapper);
        
        if (subtaskCount > 0) {
            throw new BusinessException("存在子任务，无法删除");
        }
        
        boolean result = removeById(id);
        
        if (result) {
            log.info("用户 {} 删除任务: {}", userId, task.getTitle());
            // TODO: 清理相关数据、发送通知等
        }
        
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateTaskStatus(String id, Integer status, String userId, String remark) {
        Task task = getById(id);
        if (task == null) {
            throw new BusinessException("任务不存在");
        }
        
        // 权限检查
        if (!checkTaskPermission(task, userId, "edit")) {
            throw new BusinessException("无权限修改任务状态");
        }
        
        Integer oldStatus = task.getStatus();
        task.setStatus(status);
        
        // 根据状态设置时间
        LocalDateTime now = LocalDateTime.now();
        switch (status) {
            case 2: // 进行中
                if (task.getActualStartTime() == null) {
                    task.setActualStartTime(now);
                }
                break;
            case 3: // 已完成
                task.setActualEndTime(now);
                task.setProgress(100);
                task.setCompletionRate(100);
                break;
            case 4: // 已取消
            case 5: // 已暂停
                // 保持当前时间记录
                break;
        }
        
        boolean result = updateById(task);
        
        if (result) {
            log.info("用户 {} 将任务 {} 状态从 {} 更改为 {}", userId, task.getTitle(), oldStatus, status);
            // TODO: 记录状态变更日志、发送通知、更新父任务进度等
        }
        
        return result;
    }

    @Override
    public Boolean startTask(String id, String userId) {
        return updateTaskStatus(id, 2, userId, "开始任务");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean completeTask(String id, String userId, Double actualHours, String completionNote) {
        Task task = getById(id);
        if (task == null) {
            throw new BusinessException("任务不存在");
        }
        
        if (actualHours != null) {
            task.setActualHours(java.math.BigDecimal.valueOf(actualHours));
        }
        
        boolean result = updateTaskStatus(id, 3, userId, completionNote);
        
        if (result && actualHours != null) {
            updateById(task);
        }
        
        return result;
    }

    @Override
    public Boolean pauseTask(String id, String userId, String reason) {
        return updateTaskStatus(id, 5, userId, reason);
    }

    @Override
    public Boolean cancelTask(String id, String userId, String reason) {
        return updateTaskStatus(id, 4, userId, reason);
    }

    @Override
    public PageResult<TaskVO> getMyTasks(TaskQuery query, String userId) {
        Page<Task> page = query.toPage();

        LambdaQueryWrapper<Task> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Task::getAssigneeId, userId)
               .in(query.getStatusList() != null && !query.getStatusList().isEmpty(), Task::getStatus, query.getStatusList())
               .orderByDesc(Task::getCreateTime);

        IPage<Task> result = page(page, wrapper);

        List<TaskVO> voList = result.getRecords().stream()
            .map(task -> convertToVO(task, userId))
            .collect(Collectors.toList());

        return new PageResult<>(voList, result.getTotal(), result.getCurrent(), result.getSize());
    }

    @Override
    public List<TaskVO> getTodayTasks(String userId) {
        LocalDateTime startOfDay = LocalDateTime.now().withHour(0).withMinute(0).withSecond(0);
        LocalDateTime endOfDay = LocalDateTime.now().withHour(23).withMinute(59).withSecond(59);
        
        LambdaQueryWrapper<Task> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Task::getAssigneeId, userId)
               .in(Task::getStatus, 1, 2) // 待办或进行中
               .and(w -> w.between(Task::getPlannedStartTime, startOfDay, endOfDay)
                         .or()
                         .between(Task::getPlannedEndTime, startOfDay, endOfDay))
               .orderByAsc(Task::getPriority)
               .orderByAsc(Task::getPlannedEndTime);
        
        List<Task> tasks = list(wrapper);
        
        return tasks.stream()
            .map(task -> convertToVO(task, userId))
            .collect(Collectors.toList());
    }

    // ==================== 辅助方法 ====================

    /**
     * 转换为VO对象
     */
    private TaskVO convertToVO(Task task, String userId) {
        TaskVO vo = BeanCopyUtils.copyBean(task, TaskVO.class);
        
        // 设置状态文本
        vo.setStatusText(getStatusText(task.getStatus()));
        
        // 设置优先级文本和颜色
        vo.setPriorityText(getPriorityText(task.getPriority()));
        vo.setPriorityColor(getPriorityColor(task.getPriority()));
        
        // 设置任务类型文本
        TaskType taskType = task.getTaskType();
        vo.setTaskTypeText(taskType != null ? taskType.getName() : "未知");
        
        // 设置权限
        vo.setCanEdit(checkTaskPermission(task, userId, "edit"));
        vo.setCanDelete(checkTaskPermission(task, userId, "delete"));
        vo.setCanAssign(checkTaskPermission(task, userId, "assign"));
        
        // 设置时间相关
        if (task.getPlannedEndTime() != null) {
            LocalDateTime now = LocalDateTime.now();
            if (task.getPlannedEndTime().isBefore(now) && !task.getStatus().equals(3)) {
                vo.setIsOverdue(true);
                vo.setOverdueDays((int) java.time.Duration.between(task.getPlannedEndTime(), now).toDays());
            } else {
                vo.setIsOverdue(false);
                vo.setRemainingDays((int) java.time.Duration.between(now, task.getPlannedEndTime()).toDays());
            }
        }
        
        // 设置标签列表
        if (StringUtils.hasText(task.getTags())) {
            vo.setTagList(List.of(task.getTags().split(",")));
        }
        
        // TODO: 设置其他关联数据（子任务、评论、附件等）
        
        return vo;
    }

    /**
     * 检查任务权限
     */
    private Boolean checkTaskPermission(Task task, String userId, String action) {
        // 创建者拥有所有权限
        if (task.getCreatorId().equals(userId)) {
            return true;
        }
        
        // 负责人拥有编辑权限
        if (task.getAssigneeId() != null && task.getAssigneeId().equals(userId)) {
            return !"delete".equals(action);
        }
        
        // TODO: 检查协作者权限、项目权限等
        
        return false;
    }

    /**
     * 获取状态文本
     */
    private String getStatusText(Integer status) {
        switch (status) {
            case 1: return "待办";
            case 2: return "进行中";
            case 3: return "已完成";
            case 4: return "已取消";
            case 5: return "已暂停";
            default: return "未知";
        }
    }

    /**
     * 获取优先级文本
     */
    private String getPriorityText(Integer priority) {
        switch (priority) {
            case 1: return "低";
            case 2: return "中";
            case 3: return "高";
            case 4: return "紧急";
            default: return "未知";
        }
    }

    /**
     * 获取优先级颜色
     */
    private String getPriorityColor(Integer priority) {
        switch (priority) {
            case 1: return "#52c41a"; // 绿色
            case 2: return "#1890ff"; // 蓝色
            case 3: return "#fa8c16"; // 橙色
            case 4: return "#f5222d"; // 红色
            default: return "#d9d9d9"; // 灰色
        }
    }

    /**
     * 获取任务类型文本
     */
    private String getTaskTypeText(Integer taskType) {
        switch (taskType) {
            case 1: return "个人任务";
            case 2: return "团队任务";
            case 3: return "项目任务";
            default: return "未知";
        }
    }

    // ==================== 未实现的方法（返回默认值） ====================

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean batchDeleteTasks(List<String> ids, String userId) {
        for (String id : ids) {
            deleteTask(id, userId);
        }
        return true;
    }

    @Override
    public Boolean assignTask(String taskId, String assigneeId, Integer assignmentType, Integer rolePermission, String note, String userId) {
        // TODO: 实现任务分配
        return false;
    }

    @Override
    public Boolean batchAssignTask(String taskId, List<String> assigneeIds, Integer assignmentType, String userId) {
        // TODO: 实现批量分配
        return false;
    }

    @Override
    public Boolean unassignTask(String taskId, String assigneeId, String userId) {
        // TODO: 实现取消分配
        return false;
    }

    @Override
    public Boolean acceptAssignment(String assignmentId, String userId) {
        // TODO: 实现接受分配
        return false;
    }

    @Override
    public Boolean rejectAssignment(String assignmentId, String reason, String userId) {
        // TODO: 实现拒绝分配
        return false;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateTaskProgress(String id, Integer progress, String userId, String note) {
        Task task = getById(id);
        if (task == null) {
            throw new BusinessException("任务不存在");
        }

        // 权限检查
        if (!checkTaskPermission(task, userId, "edit")) {
            throw new BusinessException("无权限更新任务进度");
        }

        // 验证进度范围
        if (progress < 0 || progress > 100) {
            throw new BusinessException("进度值必须在0-100之间");
        }

        task.setProgress(progress);

        // 如果进度达到100%，自动设置为已完成
        if (progress == 100 && !task.getStatus().equals(3)) {
            task.setStatus(3);
            task.setActualEndTime(LocalDateTime.now());
            task.setCompletionRate(100);
        }

        boolean result = updateById(task);

        if (result) {
            log.info("用户 {} 更新任务 {} 进度为 {}%", userId, task.getTitle(), progress);
            // TODO: 记录进度日志、发送通知、更新父任务进度等
        }

        return result;
    }

    @Override
    public Boolean logWorkHours(String id, Double hours, String description, String userId) {
        // TODO: 实现工时记录
        return false;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean createSubtask(String parentId, Task subtask, String userId) {
        Task parentTask = getById(parentId);
        if (parentTask == null) {
            throw new BusinessException("父任务不存在");
        }

        // 权限检查
        if (!checkTaskPermission(parentTask, userId, "edit")) {
            throw new BusinessException("无权限在该任务下创建子任务");
        }

        // 设置子任务信息
        subtask.setParentId(parentId);
        subtask.setProjectId(parentTask.getProjectId());

        boolean result = createTask(subtask, userId);

        if (result) {
            // 更新父任务子任务数量
            parentTask.setSubtaskCount(parentTask.getSubtaskCount() + 1);
            updateById(parentTask);

            log.info("用户 {} 在任务 {} 下创建子任务: {}", userId, parentTask.getTitle(), subtask.getTitle());
        }

        return result;
    }

    @Override
    public List<TaskVO> getSubtasks(String parentId, String userId) {
        LambdaQueryWrapper<Task> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Task::getParentId, parentId)
               .orderByAsc(Task::getSortOrder)
               .orderByDesc(Task::getCreateTime);

        List<Task> subtasks = list(wrapper);

        return subtasks.stream()
            .map(task -> convertToVO(task, userId))
            .collect(Collectors.toList());
    }

    @Override
    public Boolean moveSubtask(String taskId, String newParentId, String userId) {
        // TODO: 实现子任务移动
        return false;
    }

    @Override
    public Boolean addTaskDependency(String predecessorId, String successorId, Integer dependencyType, Integer lagDays, String userId) {
        // TODO: 实现依赖添加
        return false;
    }

    @Override
    public Boolean removeTaskDependency(String dependencyId, String userId) {
        // TODO: 实现依赖移除
        return false;
    }

    @Override
    public Boolean followTask(String taskId, String userId) {
        // TODO: 实现任务关注
        return false;
    }

    @Override
    public Boolean unfollowTask(String taskId, String userId) {
        // TODO: 实现取消关注
        return false;
    }

    @Override
    public PageResult<TaskVO> getMyCreatedTasks(String userId, Integer pageNum, Integer pageSize) {
        Page<Task> page = new Page<>(pageNum, pageSize);

        LambdaQueryWrapper<Task> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Task::getCreatorId, userId)
               .orderByDesc(Task::getCreateTime);

        IPage<Task> result = page(page, wrapper);

        List<TaskVO> voList = result.getRecords().stream()
            .map(task -> convertToVO(task, userId))
            .collect(Collectors.toList());

        return PageResult.of(voList, result.getTotal());
    }

    @Override
    public PageResult<TaskVO> getMyFollowedTasks(String userId, Integer pageNum, Integer pageSize) {
        // TODO: 实现我关注的任务查询
        return PageResult.of(List.of(), 0L);
    }

    @Override
    public PageResult<TaskVO> getOverdueTasks(String userId, Integer pageNum, Integer pageSize) {
        Page<Task> page = new Page<>(pageNum, pageSize);

        LocalDateTime now = LocalDateTime.now();

        LambdaQueryWrapper<Task> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Task::getAssigneeId, userId)
               .in(Task::getStatus, 1, 2) // 待办或进行中
               .lt(Task::getPlannedEndTime, now) // 计划结束时间小于当前时间
               .orderByAsc(Task::getPlannedEndTime);

        IPage<Task> result = page(page, wrapper);

        List<TaskVO> voList = result.getRecords().stream()
            .map(task -> convertToVO(task, userId))
            .collect(Collectors.toList());

        return PageResult.of(voList, result.getTotal());
    }

    @Override
    public List<TaskVO> getWeekTasks(String userId) {
        LocalDateTime startOfWeek = LocalDateTime.now().with(java.time.DayOfWeek.MONDAY).withHour(0).withMinute(0).withSecond(0);
        LocalDateTime endOfWeek = startOfWeek.plusDays(6).withHour(23).withMinute(59).withSecond(59);

        LambdaQueryWrapper<Task> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Task::getAssigneeId, userId)
               .in(Task::getStatus, 1, 2) // 待办或进行中
               .and(w -> w.between(Task::getPlannedStartTime, startOfWeek, endOfWeek)
                         .or()
                         .between(Task::getPlannedEndTime, startOfWeek, endOfWeek))
               .orderByAsc(Task::getPriority)
               .orderByAsc(Task::getPlannedEndTime);

        List<Task> tasks = list(wrapper);

        return tasks.stream()
            .map(task -> convertToVO(task, userId))
            .collect(Collectors.toList());
    }

    @Override
    public Map<String, Object> getTaskStatistics(String userId, String projectId, LocalDateTime startTime, LocalDateTime endTime) {
        // TODO: 实现任务统计
        return Map.of();
    }

    @Override
    public List<Map<String, Object>> getTaskCompletionTrend(String userId, Integer days) {
        // TODO: 实现完成趋势
        return List.of();
    }

    @Override
    public List<Map<String, Object>> getTaskPriorityDistribution(String userId, String projectId) {
        // TODO: 实现优先级分布
        return List.of();
    }

    @Override
    public Boolean createTaskFromTemplate(String templateId, Map<String, Object> customData, String userId) {
        // TODO: 实现模板创建
        return false;
    }

    @Override
    public Boolean saveAsTemplate(String taskId, String templateName, String userId) {
        // TODO: 实现保存模板
        return false;
    }

    @Override
    public String exportTasks(List<String> taskIds, String format, String userId) {
        // TODO: 实现任务导出
        return null;
    }

    @Override
    public Map<String, Object> importTasks(String filePath, String userId) {
        // TODO: 实现任务导入
        return Map.of();
    }
}
